﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Serialization;

namespace Eugenhome.Atrium.Bookmark
{
    /// <summary>
    /// 
    /// </summary>
    [XmlInclude(typeof(Bookmark))]
    public class BookmarkCollection
    {
        /// <summary></summary>
        internal const string LABEL_SPLITTER = ";";

        /// <summary></summary>
        private string _selectedLabel;

        /// <summary></summary>
        public string SelectedLabel
        {
            get
            {
                if (_selectedLabel == null && !BookmarkList.Count.Equals(0))
                {
                    SelectedLabel = LabelList[0];
                }

                return _selectedLabel;
            }
            set
            {
                _selectedLabel = value;
            }
        }

        /// <summary></summary>
        public List<Bookmark> BookmarkList = new List<Bookmark>();

        /// <summary></summary>
        private string _dataFullFileName ="bookmark.xml";// Path.GetFullPath("bookmark.xml");

        /// <summary></summary>
        [XmlIgnore]
        public string DataFullFileName { get { return _dataFullFileName; } set { _dataFullFileName = value; } }

        /// <summary></summary>
        private DAO _dao = new DAO();

        /// <summary></summary>
        [XmlIgnore]
        public List<string> Errors = new List<string>();

        /// <summary></summary>
        [XmlIgnore]
        public List<string> LabelList { get { return BookmarkList.SelectMany(item => item.Labels).Distinct().OrderBy(item => item).ToList(); } }

        /// <summary></summary>
        [XmlIgnore]
        public string PrivateKey = "";

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public List<Bookmark> GetBookmarks()
        {
            List<Bookmark> result = BookmarkList.Where(item => item.Labels.Contains(SelectedLabel)).OrderBy(item => item.DisplayName).ToList();

            //int sortIndex = 0;
            //result.ForEach(item => item.Sort = sortIndex++);

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="selectedLabel"></param>
        public void SetSelectedLabel(string selectedLabel)
        {
            SelectedLabel = selectedLabel;

            BookmarkCollection bc = new BookmarkCollection();
            bc.DataFullFileName = DataFullFileName;
            bc.Load();
            bc.SelectedLabel = selectedLabel;
            bc.Save();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="bookmark"></param>
        public void Add(Bookmark bookmark)
        {
            bookmark._parentCollection = this;
            bookmark.ID = BookmarkList.Count.Equals(0) ? 0 : BookmarkList.Max(item => item.ID) + 1;
            bookmark.Sort = BookmarkList.Count.Equals(0) ? 0 : BookmarkList.Max(item => item.Sort) + 1;

            BookmarkList.Add(bookmark);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="bookmark"></param>
        public void Delete(Bookmark bookmark)
        {
            Delete(bookmark.ID);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        public void Delete(int id)
        {
            Bookmark bookmark = BookmarkList.Where(item => item.ID.Equals(id)).FirstOrDefault();
            if (bookmark != null)
            {
                BookmarkList.Remove(bookmark);
                Save();
                Load();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        internal void Save()
        {
            _dao.Save(DataFullFileName, this, PrivateKey);
            Errors.AddRange(_dao.Errors);
        }

        /// <summary>
        /// 
        /// </summary>
        public void Load()
        {
            BookmarkCollection loadedobj = (BookmarkCollection)_dao.Load(DataFullFileName, this.GetType(), PrivateKey);
            Errors.AddRange(_dao.Errors);

            loadedobj.DataFullFileName = DataFullFileName;

            BookmarkList = loadedobj.BookmarkList.OrderBy(item=>item.Sort).ToList();
            SelectedLabel = loadedobj.SelectedLabel;

            BookmarkList.ForEach(item => item._parentCollection = this);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="filename"></param>
        public void ImportFromGoogle(string filename)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(filename);

            foreach (XmlNode h3Node in doc.GetElementsByTagName("H3").Cast<XmlNode>())
            {
                string label = h3Node.Attributes["Label"].Value;

                foreach (XmlNode aNode in h3Node.SelectNodes("A").Cast<XmlNode>())
                {
                    Bookmark bookmark = BookmarkList.Where(item => item.DisplayName.Equals(aNode.InnerText, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
                    if (bookmark == null)
                    {
                        bookmark = new Bookmark();
                        bookmark.DisplayName = aNode.InnerText;
                        bookmark.Href = aNode.Attributes["HREF"].Value;
                        bookmark.LabelsString = label;

                        Add(bookmark);
                    }
                    else
                    {
                        bookmark.LabelsString = bookmark.LabelsString + LABEL_SPLITTER + label;
                    }
                }
            }

            Save();
        }
    }
}
